package com.carrot.newsgallery.utils;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTDecodeException;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.carrot.newsgallery.entity.UserInfo;
import com.carrot.newsgallery.service.UserInfoService;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.time.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.util.Date;

@Component
public class TokenUtil {

    @Autowired
    private UserInfoService tmp;

    private static UserInfoService userInfoService;

    @PostConstruct
    public void init(){
        userInfoService = this.tmp;
    }

    public static String genToken(int userId,String password){
        return JWT.create().withAudience(Integer.toString(userId)) //保存userid到
                .withExpiresAt(DateUtils.addHours(new Date(),2))    //2h后过期
                .sign(Algorithm.HMAC256(password)); //以password作为密钥
    }

    public UserInfo getUser(String token){
        int userId = Integer.parseInt(JWT.decode(token).getAudience().get(0));
        return userInfoService.getById(userId);
    }

    public int getUserId(String token){
        return Integer.parseInt(JWT.decode(token).getAudience().get(0));
    }

    public boolean verifyToken(String token) throws MyLoginException {
        if (StringUtils.isEmpty(token))
            throw new MyLoginException(MyLoginException.errorCode.NO_TOKEN_FOUND);

        //获取token中的userid,错误则抛出异常
        int userId;
        try {
            userId = Integer.parseInt(JWT.decode(token).getAudience().get(0));
        } catch (JWTDecodeException exception){
            throw new MyLoginException(MyLoginException.errorCode.INVALID_TOKEN);
        }

        //查询用户是否存在
        UserInfo one = userInfoService.getById(userId);
        if (one == null){
            throw new MyLoginException(MyLoginException.errorCode.INVALID_TOKEN);
        }

        //验证token是否有效
        JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256(one.getPassword())).build();
        try {
            jwtVerifier.verify(token);
        } catch (JWTVerificationException exception){
            throw new MyLoginException(MyLoginException.errorCode.INVALID_TOKEN);
        }

        return true;
    }
}
